import datamodel

import logging
import utils

from google.appengine.ext import db

class HotelDataObject():
	def __init__(self):
		self.info = None
		self.reservation = None
		self.links = []

class Hotel():

	def create(self, dispatcher):
		logging.info("create")
		hotelDto = dispatcher.modelObject
		area = datamodel.Area().get(hotelDto.info.areaKey)
		hotel = datamodel.Hotel(parent=area)
		hotel.userId = dispatcher.userId
		hotel.name = hotelDto.info.name
		hotel.areaKey = str(area.key())
		hotelDto.info = hotel
		hotel.put()
		self.updateHotelLinks(dispatcher, hotel, hotelDto.links)
		area.hotels.append(hotel.key())
		area.put()
		return self.getDataForOutput(hotel, dispatcher)

	def update(self, dispatcher):
		logging.info("update")
		hotelDto = dispatcher.modelObject
		hotel = hotelDto.info
		hotelLinks = db.get(hotel.links)

		#removing all the links
		query = datamodel.HotelLink.all()
		query.filter('userId =', hotel.userId)
		query.ancestor(hotel)
		db.delete(query.fetch(200))
		#adding the links
		self.updateHotelLinks(dispatcher, hotel, hotelDto.links)

		hotel.put()
		return self.getDataForOutput(hotel, dispatcher)


	def delete(self, dispatcher):
		logging.info("delete")
		hotel= dispatcher.modelObject
		parentKey = hotel.areaKey
		hotelLinks = db.get(hotel.links)


		#removing all related entries
		query = db.Model.all()
		query.filter('userId =', hotel.userId)
		query.ancestor(hotel)
		db.delete(query.fetch(200))

		area = datamodel.Area().get(parentKey)
		area.hotels.remove(hotel.key())
		area.put();
		hotel.delete();

	def get(self, dispatcher):
		logging.info("get")
		if dispatcher.request.get("key"):
			hotel = self.getHotel(dispatcher.request.get('key'), dispatcher)
			return hotel
		elif dispatcher.request.get("area"):
			logging.info("getting all hotels for area %s", dispatcher.request.get("area"))
			query = datamodel.Hotel.all()
			query.order('name')
			if not dispatcher.isAdminData:
				query.filter('userId =', dispatcher.userId)
			query.filter('areaKey =', dispatcher.request.get("area"))
			hotels = query.fetch(100)

			hotelsDict = dict();
			query = datamodel.HotelLink.all()
			if not dispatcher.isAdminData:
				query.filter('userId =', dispatcher.userId)
			for hotel in hotels:
				hotelDict = dict()
				hotelDict["key"] = str(hotel.key())
				hotelDict["hotelInfo"] = hotel
				self.getHotelRelatedObjects(hotel, hotelDict, dispatcher.isAdminData)
				hotelsDict[str(hotel.key())] = hotelDict
			return hotelsDict
		else:
			logging.info("getting all hotels for user")
			query = datamodel.Hotel.all()
			query.order('name')
			if not dispatcher.isAdminData:
				query.filter('userId =', dispatcher.userId)
			hotels = query.fetch(100)
			hotelsDict = dict();
			for hotel in hotels:
				hotelDict = dict()
				hotelDict["key"] = str(hotel.key())
				hotelDict["hotelInfo"] = hotel
				self.getHotelRelatedObjects(hotel, hotelDict, dispatcher.isAdminData)
				hotelsDict[str(hotel.key())] = hotelDict
			return hotelsDict


	def decode(self, decodeType, inputStr, inputObj, dispatcher):
		decoder = utils.GqlDecoder()
		mydict = decoder.decode2dict(inputStr)
		hotelDto = HotelDataObject()
		if inputObj == None:
			inputObj = datamodel.Hotel()
		hotelDto.info = decoder.updateObj4Dict(mydict["hotelInfo"], inputObj)
		if "reservation" in mydict:
			hotelDto.reservation = decoder.updateObj4Dict(mydict["reservation"], inputObj)
		if "links" in mydict:
			for linkInstance in mydict["links"]:
				hotelLink = datamodel.HotelLink()
				linkData = decoder.updateObj4Dict(linkInstance, hotelLink)
				hotelDto.links.append(linkData)
		return hotelDto
				
	def encode(self, decodeType, outputObj, dispatcher):
		return utils.GqlEncoder().encode(outputObj)

	def getHotel(self, key, dispatcher):
		hotel = datamodel.Hotel().get(key)
		if not dispatcher.isAdmin:
			if (hotel.userId != dispatcher.userId):
				raise Exception("No Permissions")
		return hotel

	def getDataForOutput(self, hotel, dispatcher):
		hotelDict = dict()
		hotelDict["key"] = str(hotel.key())
		hotelDict["hotelInfo"] = hotel
		self.getHotelRelatedObjects(hotel, hotelDict, dispatcher.isAdminData)
		return hotelDict

	def getHotelRelatedObjects(self, hotel, hotelDict, isAdminData):
		# get links
		query = datamodel.HotelLink.all()
		if not isAdminData:
			query.filter('userId =', hotel.userId)
		query.ancestor(hotel)
		hotelDict["links"]= query.fetch(10)
		# get reservation
		query = datamodel.HotelReservation.all()
		if not isAdminData:
			query.filter('userId =', hotel.userId)
		query.ancestor(hotel)
		hotelReservation = query.get()
		hotelDict["reservation"]=hotelReservation 


	def updateHotelLinks(self, dispatcher, hotel, hotelLinks):		
		logging.info("updating hotel links")
		hotelKey = str(hotel.key())
		for link in hotelLinks:
			if link.link:
				logging.info("updating link %s links", link.link)
				hotelLink = datamodel.HotelLink(parent=hotel)
				hotelLink.link = link.link
				hotelLink.linkConfigKey = link.linkConfigKey
				hotelLink.hotelKey = hotelKey 
				hotelLink.userId = dispatcher.userId
				hotelLink.put()
				hotel.links.append(hotelLink.key())

